﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MaxLeaf.KH.Contract;
using MaxLeaf.KH.DataContract;
using CommonsLib.Utility;
using System.Xml;
using System.Web;
using CommonsLib.DB;
using MaxLeaf.DataFunction;
using System.Data.Common;
using System.Data;
using System.Collections;
using System.Reflection;
using CommonsLib.ORM;
using CommonsLib.Settings;

namespace MaxLeaf.KH.DALImplementation
{
    public class BaseDAL  
    {
         
        
        public ConnectionInfo GetConnectionInfo(string strDBName)
        {
            return MaxLeaf.KH.Settings.Configs.GetConnectionInfo(strDBName);
        }


        public virtual object Select ( object model ,int intKeyValue)
        {
             
            Type type=model.GetType();

            string strDBName = ORMFunc.GetDBName(type);
            string strTableName = ORMFunc.GetTableName(type);
            string strKeyName = ORMFunc.GetKey(type);
            string strFields =  ORMFunc.GetFields(type,true );
             
            ConnectionInfo conInfo = GetConnectionInfo(strDBName);
            using (DBAccess dbcon = new DBAccess(conInfo))
            {
                KeyValuePair<string, IDataParameter[]> kvp = dbcon.CreateCondParam(new Dictionary<string, object>() { { strKeyName, intKeyValue } });
                string strSql = string.Format("select {2} from {0} where {1}", strTableName, kvp.Key, strFields);

                Hashtable HashValues = new Hashtable();
                using (DbDataReader rdr = dbcon.GetDataFirstRow(strSql, kvp.Value))
                {
                    if (!rdr.Read()) return null;
                    ORMFunc.Read(model , rdr);                    
                    
                }

                
            }

            return model;
        }

        public virtual List<object> SelectDtl(object model, int intForeignKeyValue)
        {
            List<object> lst = new List<object>();

            Type type = model.GetType();
            

            string strDBName = ORMFunc.GetDBName(type);
            string strTableName = ORMFunc.GetTableName(type);
            string strKeyName = ORMFunc.GetKey(type);
            string strForeignKeyName = ORMFunc.GetForeignKey(type);
            string strFields = ORMFunc.GetFields(type, true);

            ConnectionInfo conInfo = GetConnectionInfo(strDBName);
            using (DBAccess dbcon = new DBAccess(conInfo))
            {
                KeyValuePair<string, IDataParameter[]> kvp = dbcon.CreateCondParam(new Dictionary<string, object>() { { strForeignKeyName, intForeignKeyValue } });
                string strSql = string.Format("select {2} from {0} where {1} order by {3}", strTableName, kvp.Key, strFields, strKeyName);

                Hashtable HashValues = new Hashtable();
                using (DbDataReader rdr = dbcon.GetDataReader(strSql, kvp.Value))
                {
                    while (rdr.Read())
                    {
                        model = System.Activator.CreateInstance(type);
                        ORMFunc.Read(model, rdr);
                        lst.Add(model);
                    }

                }


            }

            return lst;
        }

        public virtual object Add (object model)
        {
            return Add(model, true);
        }
        public virtual object Add(object model, bool blnNeedTrans) 
        {
            Type type = model.GetType();

            string strDBName = ORMFunc.GetDBName(type);
            string strTableName = ORMFunc.GetTableName(type);
            string strKeyName = ORMFunc.GetKey(type);
            string strFields = ORMFunc.GetFields(type, true);



            ConnectionInfo conInfo = GetConnectionInfo(strDBName);
            using (DBAccess dbcon = new DBAccess(conInfo))
            {
                if (blnNeedTrans)
                {
                    dbcon.BeginTrans();
                }
                try
                {
                    object[] datas = ORMFunc.GetValues(model);
                    
                    KeyValuePair<string, IDataParameter[]> kvp = dbcon.CreateParamSql(strFields, strTableName, datas, DBAccess.LogStatus_Add, strKeyName,null);
                    string strIdentity = dbcon.GetValue(kvp.Key, kvp.Value);
                    ORMFunc.SetIdentityValue(model,strIdentity);

                    if (blnNeedTrans)
                    {
                        dbcon.CommitTrans();
                    }
                }
                catch
                {
                    dbcon.RollbackTrans();
                    throw;
                }
            }

            return model;
        }

        public virtual object Update (object model)
        {
            return Update (model, true);
        }
        public virtual object Update (object model, bool blnNeedTrans)
        {
            Type type = model.GetType();

            string strDBName = ORMFunc.GetDBName(type);
            string strTableName = ORMFunc.GetTableName(type);
            string strKeyName = ORMFunc.GetKey(type);
            object objKeyFieldValue = ORMFunc.GetKeyValue(model);
            string strFields = ORMFunc.GetFields(type, true);



            ConnectionInfo conInfo = GetConnectionInfo(strDBName);
            using (DBAccess dbcon = new DBAccess(conInfo))
            {
                if (blnNeedTrans)
                {
                    dbcon.BeginTrans();
                }
                try
                {
                    object[] datas = ORMFunc.GetValues(model);
                    KeyValuePair<string, IDataParameter[]> kvp = dbcon.CreateParamSql(strFields, strTableName, datas, DBAccess.LogStatus_Update, strKeyName, objKeyFieldValue);
                    dbcon.ExecuteSql(kvp.Key, kvp.Value);

                    if (blnNeedTrans)
                    {
                        dbcon.CommitTrans();
                    }
                }
                catch
                {
                    dbcon.RollbackTrans();
                    throw;
                }
            }

            return model;
        }

        public virtual object Delete (object model)
        {
            return Delete (model, true);
        }
        public virtual object Delete (object model, bool blnNeedTrans)
        {
            Type type = model.GetType();

            string strDBName = ORMFunc.GetDBName(type);
            string strTableName = ORMFunc.GetTableName(type);
            string strKeyName = ORMFunc.GetKey(type);
            object objKeyValue = ORMFunc.GetKeyValue(model);


            ConnectionInfo conInfo = GetConnectionInfo(strDBName);
            using (DBAccess dbcon = new DBAccess(conInfo))
            {
                if (blnNeedTrans)
                {
                    dbcon.BeginTrans();
                }
                try
                {
                    Dictionary<string, object> dictCond = new Dictionary<string, object>() { { strKeyName, objKeyValue } };
                    KeyValuePair<string, IDataParameter[]> kvp = dbcon.CreateCondParam(dictCond);
                    string strSql = string.Format(@"delete from {0} where  {1}", strTableName, kvp.Key);
                    dbcon.ExecuteSql(strSql, kvp.Value);

                    if (blnNeedTrans)
                    {
                        dbcon.CommitTrans();
                    }
                }
                catch
                {
                    dbcon.RollbackTrans();
                    throw;
                }
            }

            return model;
        }



        
    }

  
}
